<script setup lang="ts">
import dayjs from 'dayjs';
import { computed, ref } from 'vue';
import { ClinicScheduleApi } from '@/api/clinic-schedule';
import { APPOINTMENT_STATUS } from '@/enums/registration.enums';
import { useRequest } from '@/hooks/useRequest';
import { currRoute } from '@/utils/router.utils';

// 定义数据结构
interface DateItem {
  date: dayjs.Dayjs
  // 日期是否在可预约范围内
  available: boolean
  // 日期是否有号
  hasNumber: boolean
  // 日期是否可选
  disabled: boolean
}

const props = withDefaults(defineProps<{
  // 最大可提前预约天数
  maxAdvanceDays?: number
  // 选择的日期
  value?: dayjs.Dayjs
  // 医生id
  doctorId?: string | number
}>(), {
  maxAdvanceDays: 15
});

const emit = defineEmits<{
  'change': [date: dayjs.Dayjs]
  'update:value': [date: dayjs.Dayjs]
}>();

const { query } = currRoute();

const {
  data: clinicListDays
} = useRequest(
  () => ClinicScheduleApi.getDoctorClinicListDays(Number(query.sectionId), props.doctorId as number),
  {
    onSuccess: res => {
      // 找到最近可预约的天
      const firstAvailableDate = res.find(item => item.isNumbered === APPOINTMENT_STATUS.HAVE);
      if (firstAvailableDate) {
        handleSelectDate({
          date: dayjs(firstAvailableDate.localDate),
          available: true,
          hasNumber: true,
          disabled: false
        });
      }
    }
  }
);

// 生成周标签 -- 周一、周二...周日
const weekLabels = ref(Array.from({ length: 7 })
  .fill(dayjs().startOf('week'))
  .map((item: dayjs.Dayjs, index) => {
    return item.add(index, 'day').format('周dd');
  }));

// 判断今天是周几
const diff = dayjs().diff(dayjs().startOf('week'), 'day');

// 开始日期
const startDate = dayjs().subtract(diff, 'day');

// 保证长度被7整除
const len = props.maxAdvanceDays + diff;
const padding = 7 - len % 7;

// 获取当前日期往后加预约天数
const rangeDates = Array.from({ length: padding + len }).fill(startDate).map((item: dayjs.Dayjs, index) => {
  return item.add(index, 'day');
});

const clinicRangeDates = computed(() => {
  return rangeDates.reduce((acc, cur, index) => {
    if (index % 7 === 0) {
      acc.push([]);
    }
    const targetDate = clinicListDays.value?.find(item => item.localDate === cur.format('YYYY-MM-DD'));
    const hasNumber = targetDate?.isNumbered === APPOINTMENT_STATUS.HAVE;
    const available = targetDate !== undefined;
    const disabled = !available || !hasNumber;
    acc[acc.length - 1].push({
      date: cur,
      hasNumber: targetDate?.isNumbered === APPOINTMENT_STATUS.HAVE,
      available: targetDate !== undefined,
      disabled
    });
    return acc;
  }, [] as DateItem[][]);
});

const selectDate = ref<dayjs.Dayjs>(props.value || dayjs());

// 选择日期
function handleSelectDate(item: DateItem) {
  if (item.disabled)
    return;
  selectDate.value = item.date;
  emit('update:value', item.date);
  emit('change', item.date);
}
</script>

<template>
  <view class="calendar px-44 py-35">
    <slot name="header" />

    <view class="calendar-week flex">
      <view
        v-for="(item, index) in weekLabels" :key="item" class="box-border flex-1 px-16"
        :class="[{ 'pl-0': index === 0, 'pr-0': index === 6 }]"
      >
        <view class="week-item">
          {{ item }}
        </view>
      </view>
    </view>

    <view class="calendar-month">
      <view v-for="(clinicRangeDate, index) in clinicRangeDates" :key="index" class="mt-20 flex">
        <view
          v-for="(item, clinicRangeDateIndex) in clinicRangeDate" :key="item.date.format('YYYY-MM-DD')"
          class="month-wrapper flex-1 px-16"
          :class="[{ 'pl-0': clinicRangeDateIndex === 0, 'pr-0': clinicRangeDateIndex === 6 }]"
        >
          <view
            class="month-item"
            :class="[{ disabled: item.disabled }, { active: selectDate.isSame(item.date, 'day') }]"
            @click="handleSelectDate(item)"
          >
            <view class="month-item__day">
              {{ item.date.format('DD') }}
            </view>
            <view class="month-item__number">
              {{ item.available ? item.hasNumber ? '有号' : '无号' : '-' }}
            </view>
          </view>
        </view>
      </view>
    </view>

    <view class="status-wrapper flex items-center">
      <wd-checkbox shape="square">
        可预约
      </wd-checkbox>
      <wd-checkbox shape="square" :model-value="true">
        已选择
      </wd-checkbox>
      <wd-checkbox disabled shape="square">
        无号源
      </wd-checkbox>
    </view>
  </view>
</template>

<style lang="scss" scoped>
.calendar {
  background: #e2ecfc;
  border-radius: 20px;
  border: 2px solid #e6effd;

  .calendar-week {
    margin-bottom: 26px;

    .week-item {
      color: #4a4a4a;
      font-size: 28px;
      font-weight: 500;

      text-align: center;
    }
  }

  .calendar-month {
    .month-wrapper {
      box-sizing: border-box;
    }

    .month-item {
      text-align: center;
      background: #ffffff;
      border-radius: 10px;
      padding: 14px 20px;

      .month-item__day {
        color: #4a4a4a;
        font-size: 30px;
        font-weight: 500;
      }

      .month-item__number {
        color: var(--primary);
        font-size: 24px;
        margin-top: 6px;
      }

      &.disabled {
        background: #eef5ff;
        color: #8b8e93;

        .month-item__day {
          color: #8b8e93;
        }

        .month-item__number {
          color: #8b8e93;
        }
      }

      &.active {
        background: var(--primary);
        color: #ffffff;

        .month-item__day {
          color: #ffffff;
        }

        .month-item__number {
          color: #ffffff;
        }
      }
    }
  }

  .status-wrapper {
    --wot-checkbox-label-fs: 24px;
    --wot-checkbox-size: 28px;
    --wot-checkbox-icon-size: 24px;
    --wot-checkbox-checked-color: var(--primary);
    margin-top: 40px;
    font-size: 24px;

    :deep(.wd-checkbox) {
      margin-right: 18px;

      .wd-checkbox__txt {
        line-height: 26px;
      }
    }
  }
}
</style>
